home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / UIFlow 1.0.1 / UIFlow Source / VSet2.0 / Src / vio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-20  |  15.8 KB  |  699 lines  |  [TEXT/????]

  1. /*****************************************************************************
  2. *              NCSA HDF Vset release 2.1
  3. *                    May 1991
  4. *
  5. * NCSA HDF Vset release 2.1 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************
  16. * Likkai Ng NCSA May 1991
  17. *
  18. * vio.c
  19. * Part of the HDF Vset interface.
  20. *
  21. * VDATAs are handled by routines in here.
  22. * PRIVATE functions manipulate vsdir and are used only within this file.
  23. * PRIVATE data structures in here pertain to vdatas in vsdir only.
  24. *
  25. *************************************************************************/
  26.  
  27. #include <stdio.h>
  28. #include "vg.h"
  29.  
  30. /* ------------------------------------------------------------------ */
  31. /*
  32. DFvsetopen and DFvsetclose
  33. */
  34. #undef DFopen
  35. #undef DFclose
  36.  
  37. PUBLIC DF * DFvsetopen (fname, access, defDDs )
  38. char * fname;
  39. int access, defDDs;
  40. {
  41.     DF * f;
  42.     f = DFopen(fname, access, defDDs);
  43.     Vinitialize(f);
  44.     /* sprintf(sjs,"DFvsetopen called\n"); zj; */
  45.     return (f);
  46. }
  47. /* ------------------------------------------------------------------ */
  48. PUBLIC int DFvsetclose (dfile)
  49. DF * dfile;
  50. {
  51.     int s;
  52.  
  53.     s = DFclose(dfile);
  54.     return (s);
  55. }
  56.  
  57. /* ------------------------------------------------------------------ */
  58. /*
  59. * Looks thru vstab for vsid and return the addr of the vdata instance
  60. * where vsid is found.
  61. * RETURNS NULL if error or not found.
  62. * RETURNS vsinstance_t pointer if ok.
  63. *
  64. */
  65.  
  66. vsinstance_t * vsinstance (f,vsid)             /*@@*/
  67. DF  *f;
  68. int vsid;
  69.  
  70. {
  71.     vsinstance_t * w;
  72.     vfile_t      * vf;
  73.  
  74.     if (NULL== (vf = (vfile_t*) Get_vfile(f)))
  75.         RTNULL ("vsinstance: no such file\n");
  76.  
  77.     w = vf->vstab.next;
  78.     while (NULL != w) {
  79.         if (w->ref == vsid) return(w);
  80.         w = w->next;
  81.     }
  82.     return(NULL);
  83.  
  84. } /* vsinstance */
  85.  
  86. /* ------------------------------------------------------------------ */
  87. /*
  88. * Tests if a vdata with id vsid is in the file's vstab.
  89. * returns -1 if not found,
  90. * returns 1 if found.
  91. */
  92. int vexistvs (f,vsid)             /*@@*/
  93. DF  *f;
  94. int vsid;
  95. {
  96.     if (NULL== (vsinstance_t *) vsinstance(f,vsid))
  97.         return(-1);
  98.     else
  99.         return (1);
  100.  
  101. } /* vexistvs */
  102.  
  103. /* ------------------------------------------------------------------ */
  104. /*
  105. The following 2 routines, vpackvs and vunpackvs, packs and unpacks
  106. a VDATA structure into a compact form suitable for storing in the HDF file.
  107. */
  108.  
  109. /****
  110. CONTENTS of VS stored in HDF file with tag VSDESCTAG:
  111.     int16        interlace
  112.     int32        nvertices
  113.     int16        vsize
  114.     int16        nfields
  115.  
  116.     int16        isize[1..nfields] (internal size of each field)
  117.     int16        off[1..nfields] (internal offset of each field)
  118.     char        fname[1..nfields][FIELDNAMELENMAX]
  119.     char        vsname[VSNAMELENMAX]
  120. ****/
  121.  
  122.  
  123. #define INT16SIZE 2
  124. #define INT32SIZE 4
  125.  
  126. /* ------------------------------------------------------------------ */
  127. /*
  128. The following 2 PRIVATE routines, vpackvs and vunpackvs, packs and unpacks
  129. a VDATA structure into a compact form suitable for storing in the HDF file.
  130. */
  131.  
  132. /****
  133. CONTENTS of VS stored in HDF file with tag VSDESCTAG:
  134.     int16        interlace
  135.     int32        nvertices
  136.     int16        vsize
  137.     int16        nfields
  138.  
  139.     int16        isize[1..nfields] (internal size of each field)
  140.     int16        off[1..nfields] (internal offset of each field)
  141.     char        fname[1..nfields][FIELDNAMELENMAX]
  142.     char        vsname[VSNAMELENMAX]
  143. ****/
  144.  
  145. /* 
  146. convert a vs struct to a vspack suitable for storage in a HDF file 
  147. */
  148.  
  149. void vpackvs (vs,buf,size)         /*@@*/
  150.  
  151. VDATA *vs;
  152. int   *size;
  153. unsigned char buf[];
  154. {
  155.     int           i;
  156.     unsigned char *b, *bb;
  157.     int16         int16var;
  158.  
  159.  
  160.     bb = &buf[0];
  161.  
  162.     /* save the interlace */
  163.     b = bb;
  164.     INT16WRITE(b,vs->interlace);
  165.     bb+=INT16SIZE;
  166.  
  167.     /* save nvertices */
  168.     b = bb;
  169.     INT32WRITE(b,vs->nvertices);
  170.     bb+=INT32SIZE;
  171.  
  172.     /* save ivsize */
  173.     b = bb;
  174.     INT16WRITE(b,vs->wlist.ivsize);
  175.     bb+=INT16SIZE;
  176.  
  177.     /* save nfields */
  178.     b = bb;
  179.     INT16WRITE(b,vs->wlist.n);
  180.     bb+=INT16SIZE;
  181.  
  182.     for (i=0;i<vs->wlist.n;i++) { /* save the type */
  183.         b = bb;
  184.         INT16WRITE(b,vs->wlist.type[i]);
  185.         bb+=INT16SIZE;
  186.     }
  187.     for (i=0;i<vs->wlist.n;i++) { /* save the isize */
  188.         b = bb;
  189.         INT16WRITE(b,vs->wlist.isize[i]);
  190.         bb+=INT16SIZE;
  191.     }
  192.     for (i=0;i<vs->wlist.n;i++) { /* save the offset    */
  193.         b = bb;
  194.         INT16WRITE(b,vs->wlist.off[i]);
  195.         bb+=INT16SIZE;
  196.     }
  197.     for (i=0;i<vs->wlist.n;i++)  { /* save the order */
  198.         b = bb;
  199.         INT16WRITE(b,vs->wlist.order[i]);
  200.         bb+=INT16SIZE;
  201.     }
  202.  
  203.     /* save each field length and name - omit the null */
  204.     for (i=0;i<vs->wlist.n;i++) {
  205.         b = bb;
  206.         int16var = strlen(vs->wlist.name[i]);
  207.         INT16WRITE(b,int16var);
  208.         bb+=INT16SIZE;
  209.  
  210.         strcpy((char*) bb, vs->wlist.name[i]);
  211.         bb += strlen(vs->wlist.name[i]);
  212.     }
  213.  
  214.     /* save the vsnamelen and vsname - omit the null */
  215.     b = bb;
  216.     int16var = strlen(vs->vsname);
  217.     INT16WRITE(b,int16var);
  218.     bb+=INT16SIZE;
  219.  
  220.     strcpy((char*) bb,vs->vsname);
  221.     bb += strlen(vs->vsname);
  222.  
  223.     /* save the vsclasslen and vsclass- omit the null */
  224.     b = bb;
  225.     int16var = strlen(vs->vsclass);
  226.     INT16WRITE(b,int16var);
  227.     bb+=INT16SIZE;
  228.  
  229.     strcpy((char*) bb,vs->vsclass);
  230.     bb += strlen(vs->vsclass);
  231.  
  232.     /* save the expansion tag/ref pair */
  233.     b= bb;
  234.     INT16WRITE(b,vs->extag);
  235.     bb +=INT16SIZE;
  236.  
  237.     b= bb;
  238.     INT16WRITE(b,vs->exref);
  239.     bb +=INT16SIZE;
  240.  
  241.     /* save the version field - init to version_2 now */
  242.     b= bb;
  243.     INT16WRITE(b,vs->version);
  244.     bb +=INT16SIZE;
  245.  
  246.     /* save the 'more' field - NONE now */
  247.     b= bb;
  248.     INT16WRITE(b,vs->more);
  249.     bb +=INT16SIZE;
  250.  
  251.     *size = bb - buf + 1;
  252.  
  253. } /* vpackvs */
  254.  
  255. /* ------------------------------------------------------------------ */
  256. /* 
  257. Convert a packed form(from HDF file)  to a VDATA structure.
  258. This routine will also initalize the VDATA structure as much as it can.
  259. */
  260.  
  261. void vunpackvs (vs,buf,size)       /*@@*/
  262.  
  263. VDATA *vs;
  264. int   *size;            /* UNUSED, but retained for compatibility with vpackvs */
  265. unsigned char buf[];
  266. {
  267.     unsigned char *b, *bb;
  268.     int            i;
  269.     int                int16var;
  270.  
  271.     i = *size; /* dum */
  272.  
  273.     bb = &buf[0];
  274.  
  275.     /* retrieve interlace */
  276.     b = bb;
  277.     INT16READ(b,vs->interlace);
  278.     bb += INT16SIZE;
  279.  
  280.     /* retrieve nvertices */
  281.     b = bb;
  282.     INT32READ(b,vs->nvertices);
  283.     bb += INT32SIZE;
  284.  
  285.     /* retrieve tore ivsize */
  286.     b = bb;
  287.     INT16READ(b,vs->wlist.ivsize);
  288.     bb += INT16SIZE;
  289.  
  290.     /* retrieve nfields */
  291.     b = bb;
  292.     INT16READ(b,vs->wlist.n);
  293.     bb += INT16SIZE;
  294.  
  295.     for (i=0;i<vs->wlist.n;i++)  { /* retrieve the type */
  296.         b = bb;
  297.         INT16READ(b,vs->wlist.type[i]);
  298.         bb += INT16SIZE;
  299.     }
  300.  
  301.     for (i=0;i<vs->wlist.n;i++)  { /* retrieve the isize */
  302.         b = bb;
  303.         INT16READ(b,vs->wlist.isize[i]);
  304.         bb += INT16SIZE;
  305.     }
  306.  
  307.     for (i=0;i<vs->wlist.n;i++)  { /* retrieve the offset */
  308.         b = bb;
  309.         INT16READ(b,vs->wlist.off[i]);
  310.         bb += INT16SIZE;
  311.     }
  312.  
  313.     for (i=0;i<vs->wlist.n;i++)  { /* retrieve the order */
  314.         b = bb;
  315.         INT16READ(b,vs->wlist.order[i]);
  316.         bb += INT16SIZE;
  317.     }
  318.  
  319.     /* retrieve the field names (and each field name's length)  */
  320.     for (i=0;i<vs->wlist.n;i++) {
  321.         b = bb;
  322.         INT16READ(b,int16var); /* this gives the length */
  323.         bb += INT16SIZE;
  324.  
  325.         strncpy(vs->wlist.name[i], (char*) bb, int16var);
  326.         vs->wlist.name[i][int16var] = '\0';
  327.         bb += int16var;
  328.     }
  329.  
  330.     /* retrieve the vsname (and vsnamelen)  */
  331.     b = bb;
  332.     INT16READ(b,int16var); /* this gives the length */
  333.     bb += INT16SIZE;
  334.  
  335.     strncpy(vs->vsname, (char*) bb, int16var);
  336.     vs->vsname[int16var] = '\0';
  337.     bb += int16var;
  338.  
  339.     /* retrieve the vsclass (and vsclasslen)  */
  340.     b = bb;
  341.     INT16READ(b,int16var); /* this gives the length */
  342.     bb += INT16SIZE;
  343.  
  344.     strncpy(vs->vsclass, (char*) bb, int16var);
  345.     vs->vsclass[int16var] = '\0';
  346.     bb += int16var;
  347.  
  348.     /* retrieve the expansion tag and ref */
  349.     b = bb;
  350.     INT16READ(b,vs->extag);
  351.     bb += INT16SIZE;
  352.  
  353.     b = bb;
  354.     INT16READ(b,vs->exref);
  355.     bb += INT16SIZE;
  356.  
  357.     /* retrieve the version field */
  358.     b = bb;
  359.     INT16READ(b,vs->version);
  360.     bb += INT16SIZE;
  361.  
  362.     /* retrieve the 'more' field */
  363.     b = bb;
  364.     INT16READ(b,vs->more);
  365.     bb += INT16SIZE;
  366.  
  367.     /* **EXTRA**  fill in the machine-dependent size fields */
  368.     for (i=0;i<vs->wlist.n;i++) {
  369.         vs->wlist.esize[i] = vs->wlist.order[i] * SIZEOF(vs->wlist.type[i]);
  370.     }
  371.  
  372. } /* vunpackvs */
  373.  
  374. /* ------------------------------------------------------------------ */
  375.  
  376.  
  377.  
  378. /* ***************************************************************
  379.    VSattach: 
  380.     if vsid == -1, then
  381.     (a) if vg is "w", create a new vs in vg and attach it.
  382.                             add to vsdir, set nattach= 1, nvertices = 0.
  383.     (b) if vg is "r", forbidden.
  384.    if vsid is +ve, then
  385.     (a) if vg is "w"  => new data may be added BUT must be same format
  386.                                 as existing vdata.
  387.                                 (ie. VSsetfields must match old format exactly!!)
  388.  
  389.     (b) if vg is "r"  => look in vsdir
  390.                                 if not found,
  391.                                     fetch  vs from file, add to vsdir,  
  392.                                     set nattach= 1, nvertices = val from file.
  393.                                 if found,
  394.                                     check access of found vs
  395.                                     if "w" => being written, unstable! forbidden
  396.                                     if "r" => ok. incr nattach.
  397.     
  398.     in all cases, set the marked flag to 0.
  399.     returns NULL if error.
  400.    *************************************************************** */
  401.  
  402. PUBLIC VDATA * VSattach (f,vsid,accesstype)       /*@-@*/
  403.  
  404. DF        *f;
  405. int     vsid;
  406. char *accesstype;
  407. {
  408.     VDATA             *vs;               /* new vdata to be returned */
  409.     int                 vspacksize;
  410.     unsigned char     vspack[sizeof(VWRITELIST)];
  411.     int                access;
  412.     vsinstance_t    * w;
  413.     vfile_t            * vf;
  414.  
  415.     if (f==NULL)
  416.         RTNULL("vsattach:bad f");
  417.  
  418.     if (NULL==(vf = (vfile_t*) Get_vfile(f)))
  419.         RTNULL ("Vattach: no such file\n");
  420.  
  421.     if      ( accesstype[0]=='R' || accesstype[0]=='r') { 
  422.         access = 'r'; 
  423.     }
  424.     else if ( accesstype[0]=='W' || accesstype[0]=='w') { 
  425.         access = 'w'; 
  426.     }
  427.     else RTNULL("VSattach: bad access type");
  428.  
  429.     if (vjv) {
  430.         sprintf(sjs,"#VSATTACH:vsid=%d access=%s\n",vsid, accesstype);
  431.         zj;
  432.     }
  433.  
  434.     if (vsid < -1)    {            /* --------- ILLEGAL VSID ---------------------- */
  435.         RTNULL("VSattach:bad vsid");
  436.     }
  437.  
  438.     else if (vsid == -1) {  /* ---------- VSID IS -1 ----------------------- */
  439.         if (access == 'r') RTNULL("VSattach: may not read vsid of -1");
  440.         /* otherwise 'w' */
  441.  
  442.         /* allocate space for vs,  & zero it out  */
  443.         if ( (vs=(VDATA*) DFIgetspace(sizeof(VDATA))) == NULL)
  444.             RTNULL("VSattach: cannot getspace");
  445.         zerofill ((unsigned char*) vs,sizeof(VDATA));
  446.  
  447.         vs->oref                = vnewref(f);
  448.         if ( vs->oref < 0) RTNULL("VSattach: no more refs");
  449.         vs->otag                = VSDESCTAG;
  450.         vs->vsname[0]         = '\0';
  451.         vs->interlace        = FULL_INTERLACE; /* DEFAULT */
  452.         vs->access            = 'w';
  453.         vs->f                    = f;
  454.         vs->marked            = 0;
  455.  
  456.         vs->vsclass[0]        = '\0';
  457.         vs->extag            = 0;
  458.         vs->exref            = 0;
  459.         vs->more                = 0;
  460.         vs->version            = VSET_VERSION;
  461.  
  462.         /* attach new vs to file's vstab */
  463.         if ( NULL == (w = (vsinstance_t*) DFIgetspace(sizeof(vsinstance_t))))
  464.             RTNULL("VSattach: cannot getspace for vstab\n");
  465.  
  466.         vf->vstabtail->next = w;
  467.         vf->vstabtail      = w;
  468.         vf->vstabn++;
  469.         w->next        = NULL;
  470.  
  471.         w->ref       = vs->oref;
  472.         w->vs        = vs;
  473.         w->nattach   = 1;
  474.         w->nvertices = 0;
  475.  
  476.         return (vs);
  477.     }
  478.  
  479.  
  480.     else {                  /*  --------  VSID IS NON_NEGATIVE ------------- */
  481.  
  482.         if (access == 'w') {
  483.             RTNULL("VSattach: may not write to existing vs");
  484.         }
  485.         /* otherwise 'r' */
  486.  
  487.         if (NULL == (w = (vsinstance_t*) vsinstance (f,vsid)) )
  488.             RTNULL("VSattach: vsid not in vstab");
  489.  
  490.         if (w->vs != NULL) { /* already attached */
  491.             if ( (w->vs)->access == 'w') {
  492.                 RTNULL("VSattach: existing vs already attached for write");
  493.             }
  494.             else { /* existing vs as attached for 'r' */
  495.                 w->nattach ++;
  496.                 return (w->vs);
  497.             }
  498.         }
  499.         else { /* need to fetch from file */
  500.  
  501.             if (-1 ==  DFgetelement(f,VSDESCTAG,vsid,vspack) )
  502.                 RTNULL("VSattach: vs  not in file");
  503.  
  504.             /* allocate space for vs,  & zero it out  */
  505.             if ( (vs=(VDATA*) DFIgetspace(sizeof(VDATA))) == NULL)
  506.                 RTNULL("VSattach: cannot getspace");
  507.             zerofill((unsigned char*) vs,sizeof(VDATA));
  508.  
  509.             /* unpack the vs, then init all other fields in it */
  510.             vunpackvs (vs,vspack,&vspacksize);
  511.             vs->otag                = VSDESCTAG;
  512.             vs->oref                = vsid;
  513.             vs->access            = 'r';
  514.             vs->f                    = f;
  515.             vs->vpos             = 0;
  516.             vs->marked            = 0;
  517.  
  518.             /* attach vs to vsdir  at the vdata instance w */
  519.             w->vs        = vs;
  520.             w->nattach   = 1;
  521.             w->nvertices = vs->nvertices;
  522.  
  523.             return(vs);
  524.         }
  525.     }
  526.  
  527. } /* VSattach */
  528.  
  529. /* ------------------------------------------------------------------ */
  530.  
  531. /* *************************************************************** 
  532.      Detach vs from vstab. 
  533.  
  534.     if vs has "w" access,   ( <=> only attached ONCE! )
  535.         decr nattach.
  536.         if (nattach is not  0)  => bad error in code.
  537.         if nvertices (in vs) is 0) just free vs from vstab.
  538.  
  539.         if marked flag is 1
  540.             write out vs to file and set marked flag to 0.
  541.            free vs from vsdir.
  542.  
  543.     if vs has "r" access,   ( <=> only attached ONCE! )
  544.         decr nattach.
  545.         if (nattach is 0)   just free vs from vstab.
  546.             
  547.    *************************************************************** */
  548.  
  549. PUBLIC void VSdetach (vs)        /*@-@*/
  550.  
  551. VDATA  *vs;
  552. {
  553.     int                i, vspacksize;
  554.     unsigned char  vspack[sizeof(VWRITELIST)];
  555.     vsinstance_t     * w;
  556.     char                 ss[80];
  557.  
  558.     if (vs==NULL) RT("VSdetach: bad vs");
  559.     if (vs->otag != VSDESCTAG) return;
  560.  
  561.     /* locate vs's entry in vstab */
  562.     if (NULL ==( w = (vsinstance_t*) vsinstance (vs->f,vs->oref))) {
  563.         sprintf(sjs,"@Vdetach: vg not found\n");
  564.         zj;
  565.         return;
  566.     }
  567.  
  568.     w->nattach--;
  569.  
  570.     if (vs->access =='w') {
  571.         if (w->nattach != 0) {
  572.             sprintf(ss,"VSdetach: nattach serious error. [%d] not 0", w->nattach);
  573.             RT(ss);
  574.         }
  575.  
  576.         if (vs->marked)  { /* if marked , write out vdata's VSDESC to file */
  577.             if (vs->nvertices == 0) {
  578.             } /* if vdata is empty, don't write to file */
  579.             else {
  580.                 vpackvs(vs,vspack,&vspacksize);
  581.                 if ( DFputelement(vs->f,VSDESCTAG,vs->oref,vspack,vspacksize) == -1)
  582.                     RT("VSdetach: cannot write out vs");
  583.             }
  584.             vs->marked = 0;
  585.         }
  586.  
  587.         if (vjv && vs->nvertices<=0){
  588.             sprintf(sjs,"#VSdetach:vs->nver=%d!\n",vs->nvertices);
  589.             zj;
  590.         }
  591.  
  592.         /* remove all defined symbols */
  593.         for (i=0;i<vs->nusym;i++) DFIfreespace(vs->usym[i].name);
  594.         vs->nusym = 0;
  595.  
  596.         w->vs = NULL; /* detach vs from vsdir */
  597.         DFIfreespace(vs);
  598.     }
  599.     else { /* access was 'r' */
  600.         if (w->nattach == 0) {
  601.             w->vs = NULL; /* detach vs from vsdir */
  602.             DFIfreespace(vs);
  603.         }
  604.     }
  605.     return;
  606.  
  607. } /* VSdetach */
  608.  
  609. /* ------------------------------------------------------------------ */
  610.  
  611.  
  612. /* Visvs
  613. *  checks if an id in a vgroup refers to a VDATA
  614. *  RETURNS 1 if so
  615. *  RETURNS 0 if not, or if error.
  616. */
  617.  
  618. PUBLIC int Visvs (vg,id)           /*@-@*/
  619.  
  620. VGROUP  *vg;
  621. int id;
  622. {
  623.     int i;
  624.     for (i=0;i<vg->nvelt;i++)
  625.         if (vg->ref[i] == id && vg->tag[i]==VSDESCTAG) return(1);
  626.  
  627.     return(0);
  628.  
  629. } /* Visvs */
  630.  
  631. /* ======================================================= */
  632.  
  633. /* 
  634. returns the id of the next  VDATA from the file f .
  635. (vsid = -1 gets the 1st vDATA). 
  636. RETURNS -1 on error.
  637. RETURNS vdata id (0 or +ve integer) 
  638. */
  639.  
  640. PUBLIC int VSgetid(f,vsid)           /*@-@*/
  641.  
  642. int vsid;
  643. DF  *f;
  644. {
  645.     vsinstance_t * w;
  646.     vfile_t         * vf;
  647.  
  648.     if (vsid < -1) return(FAIL);
  649.  
  650.     if (NULL==(vf = (vfile_t*) Get_vfile(f)))
  651.         RTNEG ("VSgetid: no such file\n");
  652.  
  653.  
  654.     if (vjv) {
  655.         sprintf(sjs,"#VSgetid:vstabn is %d\n",vf->vstabn);
  656.         zj;
  657.     }
  658.  
  659.     if (vsid == -1) {
  660.         if (NULL == vf->vstab.next)
  661.             return (-1);
  662.         else
  663.             return((vf->vstab.next)->ref); /* rets 1st vdata's ref */
  664.     }
  665.  
  666.     /* look in vstab  for vsid */
  667.     w = (vf->vstab).next;
  668.     while(NULL != w) {
  669.         if (w->ref == vsid) break;
  670.         w = w->next;
  671.     }
  672.  
  673.     if (w==NULL)
  674.         return(FAIL);            /* none found */
  675.     else if (w->next == NULL)
  676.         return(FAIL);            /* this is the last vdata, no more after it */
  677.     else
  678.         return( (w->next)->ref);  /* success, return the next vdata's ref */
  679.  
  680. } /* VSgetid */
  681.  
  682. /* ------------------------------------------------------------------ */
  683. /*
  684. zero out n bytes in array x.
  685. */
  686. zerofill(x,n)           /*@@*/
  687. unsigned char* x;
  688. int n;
  689. {
  690.     register int i;
  691.     for(i=0;i<n;i++) *x++ = 0;
  692. } /* zerofill */
  693. /* ------------------------------------------------------------------ */
  694.